package com.pansky.crm.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.pansky.crm.common.mybatisplus.ApiResult;
import com.pansky.crm.common.mybatisplus.SuperServiceImpl;
import com.pansky.crm.entity.Department;
import com.pansky.crm.entity.Employee;
import com.pansky.crm.entity.vo.DepartmentVO;
import com.pansky.crm.mapper.mysql.DepartmentMapper;
import com.pansky.crm.mapper.mysql.EmployeeMapper;
import com.pansky.crm.service.DepartmentService;
import com.pansky.crm.util.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author ：zhouzhiyong
 * @date ：Created in 2021/2/26 9:31
 * @description：部门服务
 */
@Service
@DS("mysqlDb")
@Slf4j
public class DepartmentSerivceImpl extends SuperServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private DepartmentTreeService departmentTreeService;

    @Override
    public ApiResult<List<DepartmentVO>> listAllDepartmentEmployee(String departmentName) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("sort");
        List<Department> departments = departmentMapper.selectList(queryWrapper);
        List<Employee> employees = employeeMapper.selectList(new QueryWrapper<>());
        // 部门id，部门名称 map
        Map<Integer, String> departmentIdNameMap = departments.stream().collect(Collectors.toMap(Department::getId, Department::getName));
        // id，员工姓名 map
        Map<Integer, String> employeesIdNameMap = employees.stream().collect(Collectors.toMap(Employee::getId, Employee::getActualName));
        List<DepartmentVO> departmentVOList = BeanUtil.copyList(departments, DepartmentVO.class);
        if (StringUtils.isNotEmpty(departmentName)) {
            // 检索条件不为空的时候 过滤部门列表
            departmentVOList = filterDepartment(departmentVOList, departmentName);
        }
        Map<Integer, DepartmentVO> departmentMap = departmentVOList.stream().collect(Collectors.toMap(DepartmentVO :: getId, Function.identity()));
        // 获取全部员工列表
        List<Employee> employeeList = employeeMapper.selectList(new QueryWrapper<>());
        employeeList.forEach(employee -> {
            DepartmentVO departmentVO = departmentMap.get(employee.getDepartmentId());
            if (null == departmentVO) {
                return;
            }
            List<Employee> employeeDTOList = departmentVO.getEmployees();
            if (null == employeeDTOList) {
                employeeDTOList = new ArrayList<>();
            }
            employeeDTOList.add(employee);
            departmentVO.setEmployees(employeeDTOList);
        });
        List<DepartmentVO> result = departmentTreeService.buildTree(departmentVOList);
        log.info("idNameMap : {}", departmentIdNameMap);
        result.forEach(departmentVO -> {
            extracted(departmentIdNameMap, employeesIdNameMap, departmentVO.getChildrenDepartment());
            departmentVO.setManagerName(employeesIdNameMap.get(departmentVO.getManagerId()));
        });
        return ApiResult.ok(result);
    }

    private void extracted(Map<Integer, String> departmentIdNameMap, Map<Integer, String> employeesIdNameMap, List<DepartmentVO> departmentVOs) {
        if (CollectionUtils.isNotEmpty(departmentVOs)) {
            departmentVOs.forEach(departmentVO -> {
                departmentVO.setParentName(departmentIdNameMap.get(departmentVO.getParentId()));
                departmentVO.setManagerName(employeesIdNameMap.get(departmentVO.getManagerId()));
                extracted(departmentIdNameMap, employeesIdNameMap, departmentVO.getChildrenDepartment());
            });
        }
    }

    @Override
    public ApiResult<Boolean> upOrDown(Integer departmentId, Integer swapId) {
        Department departmentEntity = departmentMapper.selectById(departmentId);
        if (departmentEntity == null) {
            return ApiResult.failed("departmentEntity not exist.");
        }
        Department swapEntity = departmentMapper.selectById(swapId);
        if (swapEntity == null) {
            return ApiResult.failed("swapEntity not exist.");
        }
        Integer departmentSort = departmentEntity.getSort();
        departmentEntity.setSort(swapEntity.getSort());
        departmentMapper.updateById(departmentEntity);
        swapEntity.setSort(departmentSort);
        departmentMapper.updateById(swapEntity);
        return ApiResult.ok();
    }

    @Override
    public ApiResult<Boolean> upgrade(Integer departmentId) {
        Department departmentEntity = departmentMapper.selectById(departmentId);
        if (departmentEntity == null) {
            return ApiResult.failed("departmentEntity not exist.");
        }
        if (departmentEntity.getParentId() == null || departmentEntity.getParentId().equals(0)) {
            return ApiResult.failed("此部门已经是根节点无法移动");
        }
        Department parentEntity = departmentMapper.selectById(departmentEntity.getParentId());

        departmentEntity.setParentId(parentEntity.getParentId());
        departmentMapper.updateById(departmentEntity);
        return ApiResult.ok();
    }

    @Override
    public ApiResult<Boolean> downgrade(Integer departmentId, Integer preId) {
        Department departmentEntity = departmentMapper.selectById(departmentId);
        if (departmentEntity == null) {
            return ApiResult.failed("departmentEntity not exist.");
        }
        Department preEntity = departmentMapper.selectById(preId);
        if (preEntity == null) {
            return ApiResult.failed("preEntity not exist.");
        }
        departmentEntity.setParentId(preEntity.getId());
        departmentMapper.updateById(departmentEntity);
        return ApiResult.ok();
    }

    @Override
    public ApiResult<Boolean> removeByDepartmentId(Integer departmentId) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", departmentId);
        List<Department> departments = list(queryWrapper);
        if (CollectionUtils.isNotEmpty(departments)) {
            return ApiResult.failed("当前部门有子级部门,无法删除！");
        }
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.eq("department_id", departmentId);
        List<Employee> employeeList = employeeMapper.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(employeeList)) {
            return ApiResult.failed("当前部门下存在员工,无法删除！");
        }
        return ApiResult.ok(removeById(departmentId));
    }

    /**
     * 过滤部门名称，获取过滤后的结果
     *
     * @author lidoudou
     * @date 2019/4/28 20:17
     */
    private List<DepartmentVO> filterDepartment(List<DepartmentVO> departmentVOList, String departmentName) {
        Map<Integer, DepartmentVO> departmentMap = new HashMap<>();
        departmentVOList.forEach(item -> {
            if (!item.getName().contains(departmentName)) {
                return;
            }
            // 当前部门包含关键字
            departmentMap.put(item.getId(), item);
            Integer parentId = item.getParentId();
            if (null != parentId) {
                List<DepartmentVO> filterResult = new ArrayList<>();
                getParentDepartment(departmentVOList, parentId, filterResult);
                for (DepartmentVO dto : filterResult) {
                    if (!departmentMap.containsKey(dto.getId())) {
                        departmentMap.put(dto.getId(), dto);
                    }
                }
            }
        });
        return departmentMap.values().stream().collect(Collectors.toList());
    }

    private List<DepartmentVO> getParentDepartment(List<DepartmentVO> departmentVOList, Integer parentId, List<DepartmentVO> result) {
        List<DepartmentVO> deptList = departmentVOList.stream().filter(e -> e.getId().equals(parentId)).collect(Collectors.toList());
        for (DepartmentVO item : deptList) {
            result.add(item);
            if (ObjectUtils.isNotEmpty(item.getParentId())) {
                result.addAll(getParentDepartment(departmentVOList, item.getParentId(), result));
            }
        }
        return result;
    }
}
